﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Text;
using System.Threading;
using Client_Server_Interface.Chat;

namespace ServerLib.Entities
{
    class ChatServer
    {
        private static bool _isStarted;
        private Timer _tim = new Timer(CheckTimerCallback);

        #region old
        private readonly Socket _soc;
        
        private readonly List<ClientConnection> _clients;

        private const int LocalPort = 38002;
        private const string UnknownString = "unknown";

        public ChatServer()
        {
            _clients = new List<ClientConnection>();
            _soc = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            var localEp = new IPEndPoint(IPAddress.Any, LocalPort);
            _soc.Bind(localEp);
            var ci = new ClientConnection();
            ci.Socket = _soc;
            lock(_clients)
                _clients.Add(ci);
            _soc.BeginReceive(ci.MesBuffer, 0, ci.MesBuffer.Length, SocketFlags.None, ReceiveCallback, ci);
        }

        private void ReceiveCallback(IAsyncResult ar)
        {
            var client = (ClientConnection)ar.AsyncState;
            client.ClientEndPoint = (IPEndPoint)client.Socket.RemoteEndPoint;

            int bytesRec;
            try
            {
                bytesRec = client.Socket.EndReceive(ar);
            }
            catch (Exception)
            {
                //ToImplement
                return;
            }

            var data = client.ReadMessage(bytesRec);
            

        }

        class ClientConnection
        {
            public Socket Socket { get; set; }

            public byte[] MesBuffer { get; set; }
            public string Login = UnknownString;
            public IPEndPoint ClientEndPoint { get; set; }

            public ClientConnection()
            {
                MesBuffer = new byte[1000];
            }

            public ClientMessage ReadMessage(int mesLength)
            {
                var buff = new byte[mesLength];
                Buffer.BlockCopy(MesBuffer, 0, buff, 0, mesLength);
                var str = Encoding.UTF8.GetString(buff);
                return ClientMessage.DeserializeMessage(str);
            }
        }
        #endregion

        //ChatService
        private static ServiceHost _chatServiceHost;

        static readonly ChatService Cs = new ChatService();
        

        public static void Start()
        {
            if(_isStarted)
                return;
            var baseAddress =
                new Uri("net.tcp://localhost:38004/Chat/ChatService");
            _chatServiceHost = new ServiceHost(typeof(ChatService), baseAddress);

            _chatServiceHost.Open();

            //int i = 3;
            //while (i++ < 15)
            //{
            //    try
            //    {
            //        _chatServiceHost.Open();
            //        break;
            //    }
            //    catch (AddressAlreadyInUseException ex)
            //    {
            //        //var baseAddresses = new List<Uri> { new Uri("net.tcp://localhost:380" + i.ToString("D2") + "/Chat/ChatService") };
            //        var baseAddresses = new List<Uri> { new Uri("net.tcp://localhost:380" + i.ToString("D2") + "/Chat/ChatService") };
            //        _chatServiceHost = new ServiceHost(typeof(ChatService), baseAddresses[0]);
            //    }
            //}
            //if (i == 16)        //ServiceHost open error
            //{
                
            //}


            //ChatService.ChatListOfNames += ChatServiceOnChatListOfNames;
            _isStarted = true;
        }

        public static void Stop()
        {
            if(!_isStarted)
                return;
            Cs.Close();
            _chatServiceHost.Close();
            //ChatService.ChatListOfNames -= ChatServiceOnChatListOfNames;
            _isStarted = false;
        }

        private static void CheckTimerCallback(object state)
        {
            throw new NotImplementedException();
        }

        private static void ChatServiceOnChatListOfNames(List<string> names, object sender)
        {
            //ToImplement
        }
    }

}
